﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using com.eforceglobal.crux.BusinessObjects;
using com.eforceglobal.crux.BusinessObjects.DatabaseQueries;
using com.eforceglobal.crux.DTOs;
using com.eforceglobal.crux.exceptions;
using com.eforceglobal.crux.logging;
using com.eforceglobal.crux.logging.Enums;
using com.eforceglobal.crux.notifications;
using com.eforceglobal.crux.security.EncryptionAndHashing;
using com.eforceglobal.crux.security.EncryptionAndHashing.Enums;

namespace com.eforceglobal.crux.BusinessFacades
{
    public class ForgotPasswordFacade
    {
        private KeyValuePair<string, string> GenerateRandomPassword(PasswordStorageType passwordStorageType)
        {
            //TODO: Improove Password Generation Mechanism. First Six Characters Of Guid Are A Neat Idea
            //but find out how the rest of the world does it. .NET is supposed to have some API for this
            //becuase the membership providers renegrate forgotten passwords. 

            Guid randomKey = Guid.NewGuid();
            string randomPassword = randomKey.ToString().Substring(0, 6);
            string randomHashedPassword = randomPassword;
            if (passwordStorageType == PasswordStorageType.hashed)
                randomHashedPassword = Hasher.GetHash(randomPassword);
            KeyValuePair<string, string> NormalAndHashedPassword = new KeyValuePair<string, string>(randomPassword, randomHashedPassword);
            return NormalAndHashedPassword;
        }

        public void ResetPassword(string userName, PasswordStorageType passwordStorageType, int savedPasswordCount, bool isFeatureSupported)
        {
            PasswordFacade passwordFacade = new PasswordFacade();
            KeyValuePair<string, string> RandomAndHashedPassword = GenerateRandomPassword(passwordStorageType);
            string RandomPassword = RandomAndHashedPassword.Key;
            Queries query = new Queries();
            User dbUser = query.GetUser(userName);
            dbUser.Password = RandomAndHashedPassword.Value;
            dbUser.PasswordChangedOn = DateTime.Now;
            dbUser.IsResetPasswordNeeded = true;
            if(isFeatureSupported)
             passwordFacade.SavePassword(dbUser, savedPasswordCount, query);
            query.SubmitChanges();
            try
            {
                CreateForgotPasswordNotification forgotPassword = new CreateForgotPasswordNotification();
                forgotPassword.SendForgotPasswordNotificationToUser(dbUser.FirstName + " " + dbUser.LastName,
                                                                    RandomPassword, dbUser.UserName);
            }
            catch (Exception ex)
            {
                ApplicationLogger.LogApplicationMessage(ex.Message, ApplicationLogType.Notification, ex.StackTrace);
                throw CruxExceptionManager.CreateNewNotificationException("701");
            }
        }

        public List<SecurityQuestionInformation> GetAllSecurityQuestions()
        {
            Queries query = new Queries();
            IEnumerable<SecurityQuestionInformation> questions = from ques in query.GetAllSecurityQuestions()
                                                                 select ClassConverter.CopySecurityQuestionToSecurityQuestionInformation(ques);
            return questions.ToList();
        }

        public bool ValidateDetails(string userName, int securityQuesId, string ans)
        {
            Queries query = new Queries();
            User dbUser = query.GetUser(userName);
            if (dbUser.SecurityQuestionID == securityQuesId && dbUser.SecurityAnswer.ToLower() == ans.ToLower())
                return true;
            else
                return false;
        }
    }
}
